package math.region;

import math.math;
import math.vec2;
import math.vec3;

public class Cylinder3 implements Volume3, Surface3
{
    
    public vec3 mOrig0;
    
    public vec3 mOrig1;
    
    public double mRadius;
    
    
    public Cylinder3()
    {
        this.mOrig0 = new vec3();
        this.mOrig1 = new vec3();
        this.mRadius = 0.0;
    }
    
    public Cylinder3(
            vec3 aOrig0, 
            vec3 aOrig1, 
            double aRadius)
    {
        this();
        this.set(aOrig0, aOrig1, aRadius);
    }
    
    
    public final void set(
            vec3 aOrig0, 
            vec3 aOrig1, 
            double aRadius)
    {
        this.mOrig0.set(aOrig0);
        this.mOrig1.set(aOrig1);
        this.mRadius = aRadius;
    }
    
    public final void set(Cylinder3 aOther)
    {
        this.set(aOther.mOrig0, aOther.mOrig1, aOther.mRadius);
    }
    
    
    public boolean insideVol(vec3 aPoint)
    {
        return false;
    }
    
    public boolean onSurface(vec3 aPoint)
    {
        return false;
    }
    
    
    public double surfaceArea()
    {
        
        return -1;
    }
    
    
    public vec3 surfaceNorm(
            vec3 point, 
            vec3 referencePt)
    {
        vec3 toPt = vec3.sub(point, this.mOrig0);
        vec3 axis = vec3.sub(this.mOrig1, this.mOrig0);
        vec3 proj = vec3.proj(toPt, axis);
        vec3 perp = vec3.sub(toPt, proj);
        if (perp.lengthSq() < this.mRadius * this.mRadius)
        {
            perp.mul(-1.0);
        }
        perp.norm();
        return perp;
    }
    
    public vec3 convertParam_World(vec2 aUV)
    {
        vec3 axis = vec3.sub(this.mOrig1, this.mOrig0);
        vec3 perp = vec3.perp(axis);
        perp.norm();
        perp.mul(this.mRadius);
        return vec3.add(this.mOrig0, perp);
    }
    
    public vec2 convertWorld_Param(vec3 aPos)
    {
        return vec2.ZERO;
    }
    
    
    public Surface3 lerp(Surface3 next, double t)
    {
        return null;
    }
    
    
    public AABB3 boundingBox()
    {
        return null;
    }
    
    
    public Cylinder3 copy()
    {
        Cylinder3 copy = new Cylinder3();
        copy.set(this);
        return copy;
    }
    
    
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        sb.append("Cylinder3:\n   Orig0: ");
        sb.append(this.mOrig0);
        sb.append("\n   Orig1: ");
        sb.append(this.mOrig1);
        sb.append("\n   Radius: ");
        sb.append(this.mRadius);
        return sb.toString();
    }
    
}
